
#include "py/obj.h"
#include "py/mpstate.h"
#include "py/mphal.h"
#include "extmod/misc.h"
#include "lib/utils/pyexec.h"
#include "mphalport.h"
#include "py/stream.h"
#include "SWM320.h"

#include "FreeRTOS.h"
// int puts(const char *s) {
//     printf(s);
// 	return 0;}

const mp_print_t mp_debug_print = {NULL, 0};
void mp_hal_delay_ms(mp_uint_t ms) {
    // mdelay(ms);
    const TickType_t xDelay = ms / portTICK_PERIOD_MS;
    vTaskDelay( xDelay );
    // delay_ms(ms);
}

void mp_hal_delay_us(mp_uint_t us) {
	// void udelay(us);
    // delay_us(us);
    const TickType_t xDelay = us / 1000 / portTICK_PERIOD_MS;
    vTaskDelay( xDelay );
}
size_t mp_hal_ticks_us(void) {
    // return (size_t)SysTick->VAL;
    return (size_t)xTaskGetTickCountFromISR()/portTICK_PERIOD_MS/1000;
	// return 40;
}
size_t mp_hal_ticks_ms(void) {
    // return (size_t)SysTick->VAL;
    return (size_t)xTaskGetTickCountFromISR()/portTICK_PERIOD_MS;
	// return 40;
}
mp_uint_t mp_hal_ticks_cpu(void) {
    // return (size_t)SysTick->VAL;
    return (size_t)xTaskGetTickCountFromISR();
    // return 0; 
}

// Wake up the main task if it is sleeping
void mp_hal_wake_main_task_from_isr(void) {
    // BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    // vTaskNotifyGiveFromISR(mp_main_task_handle, &xHigherPriorityTaskWoken);
    // if (xHigherPriorityTaskWoken == pdTRUE) {
    //     portYIELD_FROM_ISR();
    // }
}


void mp_hal_stdout_tx_strn(const char *str, size_t len) {
    // Only release the GIL if many characters are being sent
    bool release_gil = len > 20;
    if (release_gil) {
        MP_THREAD_GIL_EXIT();
    }
    // printf("%s",str);
    // printf("mp_hal_stdout_tx_strn len %d\r\n",len);
    uint32_t i = 0;
    for (i =0; i < len; ++i) {
    //     uart_tx_one_char(str[i]);
        // printf("%c",*(str++));
        UART_WriteByte(UART0, *(str++));
		while(UART_IsTXBusy(UART0));
        // putchar(*(str++));
    }
    // putchar('\0');
    if (release_gil) {
        MP_THREAD_GIL_ENTER();
    }
    
    mp_uos_dupterm_tx_strn(str, len);
}
uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
    uintptr_t ret = 0;
    printf("mp_hal_stdio_poll\r\n",(poll_flags & MP_STREAM_POLL_RD));
    if ((poll_flags & MP_STREAM_POLL_RD) && 1) {
        printf("poll_flags & MP_STREAM_POLL_RD)\r\n",(poll_flags & MP_STREAM_POLL_RD));
        ret |= MP_STREAM_POLL_RD;
    }
    return ret;
}

int mp_hal_stdin_rx_chr(void) {
    //for (;;) {
    //     int c = ringbuf_get(&stdin_ringbuf);
    //     if (c != -1) {
    //         return c;
    //     }
    //     MICROPY_EVENT_POLL_HOOK
    //     ulTaskNotifyTake(pdFALSE, 1);
    // }
    int ch;
    // if((ch = getchar()) != EOF)
    // {
    //     // printf("getchar()=%c\r\n",ch);
    //     return ch;
    // }
    uint32_t err;
    if(!UART_IsRXFIFOEmpty(UART0))
    {
        err = UART_ReadByte(UART0, &ch);
        if(err == 0)
        {
            // UART_WriteByte(UART0, chr);
            return ch;
        }
        else if(err == UART_ERR_PARITY)
        {
            printf("Parity error!\r\n");
            
            while(1) __NOP();
        }
    }

    return 0;
}
